package com.apobates.forum.toro.proxy.strategy;

import com.apobates.forum.toro.proxy.MapperAttrExpression;
import com.apobates.forum.toro.proxy.MapperAttrStatements;
import com.apobates.forum.toro.utils.BeanHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Optional;
import java.util.stream.Stream;

public class MapperParallelStrategy<E,T> implements MapperStrategy<E,T> {
    private static final Logger logger = LoggerFactory.getLogger(MapperParallelStrategy.class);
    @Override
    public void consumer(Stream<MapperAttrExpression> selectExprStream, E targetObj, T selectObj) {
        logger.debug("[MPS][Parallel]one parallel strategy start");
        selectExprStream.parallel().forEach((maq)->{
            try {
                // selectAttrTypeName
                Class<?> selectAttrType = null;
                try {
                    selectAttrType = BeanHelper.getTypeClass(maq.getSelectAttrTypeName());
                }catch (Exception e){
                    logger.debug("[MPS][Parallel]calc select function argument has error:"+e.getMessage());
                }
                MapperAttrStatements.Argument args = maq.buildRelationArgs();
                // 查询函数的参数值
                Object selectAttrVal = (null == selectAttrType)
                            ? BeanHelper.getAttrVal(selectObj, maq.getSelectAttr())
                            : BeanHelper.getAttrVal(selectObj, maq.getSelectAttr(), selectAttrType);
                logger.debug("[MPS][Parallel]type of: " + selectAttrVal.getClass().getSimpleName() + ", value: " + selectAttrVal.toString());
                Object tmp = maq.getSelectFun().apply(selectAttrVal.toString());
                if(!args.isTargetAttrSet()) {
                    tmp = Optional.ofNullable(tmp).orElse(null); // Bean无值时等于null
                } else {
                    tmp =  (null==tmp) ? BeanHelper.buildInstance(Class.forName(args.getCollectionType())) : tmp; // 集合无值时等于空集合
                }
                BeanHelper.setAttrVal(targetObj, maq.getTargetAttr(), tmp);
            }catch (Exception e){
                logger.debug("[MPS][Parallel]set target attr has error:"+e.getMessage());
            }
        });
    }
}
